package com.tencent.wxpay.demo.controller;

import com.tencent.wxpay.common.Signature;
import com.tencent.wxpay.common.Util;
import com.tencent.wxpay.common.XMLParser;
import com.tencent.wxpay.demo.service.UnifiedOrderService;
import com.tencent.wxpay.demo.util.IPUtil;
import com.tencent.wxpay.protocol.response.PayResultResData;
import com.tencent.wxpay.protocol.response.UnifiedOrderResData;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * 统一下单服务控制层
 */
@Controller
@RequestMapping("unifiedOrder")
public class UnifiedOrderController {

    private Logger logger = LoggerFactory.getLogger(UnifiedOrderController.class);

    @Autowired
    private UnifiedOrderService unifiedOrderService;

    /**
     * 调用统一下单接口进行下单
     * @param openid
     * @return
     */
    @RequestMapping("doUnifiedOrder")
    @ResponseBody
    public Map<String, Object> doUnifiedOrder(HttpServletRequest request, String openid) {
        Map<String,Object> map = new HashMap();
        if(StringUtils.isNotBlank(openid)) {
          String ipAddress = IPUtil.getClientIp(request);
            String notifyUrl = "http://www.xxx.com/wxpay/unifiedOrder/callback.do";
            UnifiedOrderResData unifiedOrderResData = unifiedOrderService.doUnifiedOrder(openid,ipAddress,notifyUrl);
            if (null != unifiedOrderResData && null != unifiedOrderResData.getPrepay_id()) {
                map = unifiedOrderService.doPaySign(unifiedOrderResData);
                map.put("status", "success");
            } else {
                map.put("status","error");
                map.put("msg", "下单失败，详细信息请查看服务端日志输出");
            }
        } else {
            map.put("status","error");
            map.put("msg", "下单失败，openid不能为空");
        }
        return map;
    }

    /**
     * 支付异步回调接口
     * @param request
     * @return
     */
    @RequestMapping("callback")
    @ResponseBody
    public void callback(HttpServletRequest request, HttpServletResponse response) {
        BufferedReader bufferedReader = null;
        Map<String,Object> map = new HashMap<String, Object>();
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream()));
            String line = null;
            StringBuffer stringBuffer = new StringBuffer();
            while ((line = bufferedReader.readLine()) != null) {
                stringBuffer.append(line);
            }
            // 做签名验证通知是否可信
            logger.info("支付回调接口返回的信息为：");
            logger.info(stringBuffer.toString());
            if(Signature.checkIsSignValidFromResponseString(stringBuffer.toString())){
                PayResultResData payResultResData = (PayResultResData)Util.getObjectFromXML(stringBuffer.toString(),PayResultResData.class);
                // TODO 判断该通知是否未处理过，若没处理过，则处理业务，若处理过，则直接返回， //跳过业务处理，直接打印，这样每次都会打印，后面要改掉
                logger.info("【订单号："+payResultResData.getOut_trade_no()+"】回调接口签名验证通过，成功返回");
                map.put("return_code", "SUCCESS");
                map.put("return_msg", "OK");
            } else {
                logger.info("回调接口签名验证失败，数据可能被篡改，直接返回");
                map.put("return_code", "FAIL");
                map.put("return_msg", "签名失败");
            }
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            String result = XMLParser.getXmlFromMap(map);
            out.write(result.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
